#include "ipc.h"
#include "types.h"
#include <iostream>
#include <thread>
#include <chrono>
#include <unistd.h>
#include <csignal>
static char *SystemStateSet[] = {"IDLE", "CAPTURE", "TAIL_CAPTURE","OFFLINE_PROCESSING"};
class SupervisorProcess {
private:
    SystemState current_state = SystemState::IDLE;
    bool running = true;
    bool capture_alive = false;
    bool algo_alive = false;
    uint64_t last_capture_heartbeat = 0;
    uint64_t last_algo_heartbeat = 0;
    const uint64_t HEARTBEAT_TIMEOUT = 3000; // 3秒超时

public:
    SupervisorProcess() {
        // 注册信号处理   CTRL+C  KILLED
        signal(SIGINT, &SupervisorProcess::signal_handler);
        signal(SIGTERM, &SupervisorProcess::signal_handler);
    }

    void run() {
        sd_journal_print(LOG_INFO, "状态控制进程启动");
        std::cout << "Supervisor process started\n";

        // 启动消息接收线程
        sd_journal_print(LOG_INFO, "启动消息接收线程");
        std::thread msg_thread(&SupervisorProcess::message_loop, this);
        
        // 启动心跳检测线程
        sd_journal_print(LOG_INFO, "启动心跳检测线程");
        std::thread heartbeat_thread(&SupervisorProcess::heartbeat_monitor, this);

        // 初始状态: 等待子进程就绪
        sd_journal_print(LOG_INFO, "初始状态: 等待子进程就绪");
        std::this_thread::sleep_for(std::chrono::seconds(2));
        transition_to_state(SystemState::CAPTURE);

        msg_thread.join();
        heartbeat_thread.join();
    }

    static void signal_handler(int signum) {
        sd_journal_print(LOG_INFO, "状态监控进程收到信号 signal %d, exiting", signum);
        exit(0);
    }

private:
    void message_loop() {
        Message msg;
        while (running) {
            if (receive_message(SUPERVISOR_SOCKET, msg)) {
                handle_message(msg);
            }
            std::this_thread::sleep_for(std::chrono::milliseconds(100));
        }
    }

    void handle_message(const Message& msg) {
        switch (msg.type) {
            case MessageType::STRIKE_DETECTED:
                if (current_state == SystemState::CAPTURE) {
                    sd_journal_print(LOG_INFO, "击球发生在时间： at %llu", 
                                   (unsigned long long)msg.strike.timestamp);
                    // 转发击球事件给采集进程
                    send_message(CAPTURE_SOCKET, msg);
                }
                break;

            case MessageType::CAPTURE_FINISHED:
                if (current_state == SystemState::TAIL_CAPTURE) {
                    sd_journal_print(LOG_INFO, "采集数据完成, 开始离线分析");
                    transition_to_state(SystemState::OFFLINE_PROCESSING);
                }
                break;

            case MessageType::PROCESSING_FINISHED:
                if (current_state == SystemState::OFFLINE_PROCESSING) {
                    sd_journal_print(LOG_INFO, "离线分析完成, 返回idle状态");
                    transition_to_state(SystemState::IDLE);
                    // 短暂延迟后重新进入采集状态
                    std::thread reset_thread([this]() {
                        std::this_thread::sleep_for(std::chrono::seconds(2));
                        transition_to_state(SystemState::CAPTURE);
                    });
                    reset_thread.detach();
                }
                break;

            case MessageType::STATE_CHANGE:
                sd_journal_print(LOG_INFO, "状态机变化通知 to %d", (int)msg.state);
                break;

            case MessageType::HEARTBEAT:
                // 根据消息来源更新心跳时间
                if (msg.timestamp > last_capture_heartbeat) {
                    last_capture_heartbeat = msg.timestamp;
                    capture_alive = true;
                }
                if (msg.timestamp > last_algo_heartbeat) {
                    last_algo_heartbeat = msg.timestamp;
                    algo_alive = true;
                }
                break;

            case MessageType::ERROR:
                sd_journal_print(LOG_ERR, "Error received: %s", msg.error_msg.c_str());
                break;

            default:
                break;
        }
    }

    void transition_to_state(SystemState new_state) {
        if (current_state == new_state) return;

        sd_journal_print(LOG_INFO, " %d to %d", 
                       SystemStateSet[(int)current_state], SystemStateSet[(int)new_state]);
        current_state = new_state;

        // 通知所有子进程状态变更
        Message msg;
        msg.type = MessageType::STATE_CHANGE;
        msg.state = new_state;
        msg.timestamp = get_current_timestamp();
        
        send_message(CAPTURE_SOCKET, msg);
        send_message(ALGO_SOCKET, msg);
    }

    void heartbeat_monitor() {
        while (running) {
            // 发送心跳请求
            Message msg;
            msg.type = MessageType::HEARTBEAT;
            msg.timestamp = get_current_timestamp();
            send_message(CAPTURE_SOCKET, msg);
            send_message(ALGO_SOCKET, msg);

            // 检查超时
            uint64_t now = get_current_timestamp();
            if (now - last_capture_heartbeat > HEARTBEAT_TIMEOUT) {
                if (capture_alive) {
                    sd_journal_print(LOG_WARNING, "Capture process heartbeat timeout");
                    capture_alive = false;
                    // 请求systemd重启采集进程
                    restart_service("dual-cam-capture.service");
                }
            }

            if (now - last_algo_heartbeat > HEARTBEAT_TIMEOUT) {
                if (algo_alive) {
                    sd_journal_print(LOG_WARNING, "Algo process heartbeat timeout");
                    algo_alive = false;
                    // 请求systemd重启算法进程
                    restart_service("dual-cam-algo.service");
                }
            }

            std::this_thread::sleep_for(std::chrono::seconds(1));
        }
    }

    void restart_service(const std::string& service) {
        std::string cmd = "systemctl restart " + service;
        sd_journal_print(LOG_INFO, "Restarting service: %s", service.c_str());
        system(cmd.c_str());
    }

    uint64_t get_current_timestamp() {
        auto now = std::chrono::system_clock::now();
        auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
            now.time_since_epoch()
        );
        return ms.count();
    }
};

int main() {
    try {
        SupervisorProcess process;
        process.run();
    } catch (const std::exception& e) {
        sd_journal_print(LOG_ERR, "Supervisor error: %s", e.what());
        std::cerr << "Supervisor error: " << e.what() << "\n";
        return 1;
    }
    return 0;
}